import os
import requests
from playwright.sync_api import Playwright, sync_playwright, Page

# 打开浏览器
def open_browser(playwright: Playwright) -> Page:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()

    return browser, context, page

# 登录
def login(page: Page) -> Page:
    # 打开登录页面
    page.goto("https://www.ceppea.net/")
    page.get_by_role("link", name="你好，请登录").click()

    # 等待弹窗出现
    page.wait_for_selector("iframe[name=\"layui-layer-iframe1\"]")

    # 输入账号密码
    page.locator("iframe[name=\"layui-layer-iframe1\"]").content_frame.get_by_placeholder("请输入账号").click()
    page.locator("iframe[name=\"layui-layer-iframe1\"]").content_frame.get_by_placeholder("请输入账号").fill("")
    page.locator("iframe[name=\"layui-layer-iframe1\"]").content_frame.get_by_placeholder("请输入密码").click()
    page.locator("iframe[name=\"layui-layer-iframe1\"]").content_frame.get_by_placeholder("请输入密码").fill("")
    page.locator("iframe[name=\"layui-layer-iframe1\"]").content_frame.get_by_placeholder("请输入验证码").click()
    page.locator("iframe[name=\"layui-layer-iframe1\"]").content_frame.get_by_placeholder("请输入验证码").fill("")
    page.locator("iframe[name=\"layui-layer-iframe1\"]").content_frame.get_by_role("button", name="登 录").click()

    return page

def run(playwright: Playwright) -> None:
    # 打开浏览器
    browser, context, page = open_browser(playwright)

    # 登录
    page = login(page)

    # 跳转到 “四优”申报 评审系统 - 项目清单
    page.locator("iframe").content_frame.get_by_role("link", name="“四优”申报 评审系统").click()
    page.get_by_role("link", name="项目清单").click()

    # TODO: 等待页面加载完成
    page.wait_for_timeout(2000)

    # 循环遍历项目清单中的所有项目
    project_list_one = page.frame(name="MainRight").query_selector_all("a[href^='ProjectList']")
    project_count_one = len(project_list_one)

    project_child_frame_index = 0

    for i in range(0, project_count_one, 1):
        # 获取项目
        project_list_one = page.frame(name="MainRight").query_selector_all("a[href^='ProjectList']")

        # 获取项目名称
        project_one = project_list_one[i]
        project_name_one = project_one.text_content().strip()
        
        # 跳转到项目详情页面
        project_one.click()

        # TODO: 等待页面加载完成
        page.wait_for_timeout(3000)

        project_list_two = page.frame(name="MainRight").query_selector_all("a[href^='javascript']")
        project_count_two = len(project_list_two)

        for j in range(0, project_count_two, 1):
            # 获取项目
            project_list_two = page.frame(name="MainRight").query_selector_all("a[href^='javascript']")

            # 获取项目名称
            project_two = project_list_two[j]

            # 跳过 “查看形式检查” 和 “填写初评报告” 两个选项
            project_name_two = project_two.text_content().strip()
            if ("查看形式检查" in project_name_two) or ("填写初评报告" in project_name_two):
                continue

            # 跳转到项目详情页面
            project_two.click()

            # 点击 “查看附件” 按钮
            page.locator("iframe[name=\"MainRight\"]").content_frame.get_by_role("listitem", name="查看附件").click()

            # TODO: 等待页面加载完成
            page.wait_for_timeout(2000)

            # 获取右侧界面中的内容
            main_right = page.frame(name="MainRight")
            project_detail_main = main_right.child_frames[project_child_frame_index]
            project_child_frame_index += 1

            # 获取 pdf 文件数量，从而确定循环次数
            project_list_three = project_detail_main.query_selector_all("a[href^='javascript:__doPostBack']")
            project_count_three = len(project_list_three)

            # 循环下载 PDF 文件
            for x in range(0, project_count_three, 1):
                try:
                    # 获取 links. 加载新页面后 links 会被清理, 因此需要重新获取
                    project_list_three = project_detail_main.query_selector_all("a[href^='javascript:__doPostBack']")
                    project_three = project_list_three[x]

                    # 获取项目名称
                    project_name_three = project_three.text_content().strip()

                    # 跳过非 pdf 文件
                    if not project_name_three.endswith(".pdf"):
                        continue

                    # 提前为新页面设置网络响应监听器
                    pdf_url = None

                    def handle_response(response):
                        nonlocal pdf_url
                        if response.headers.get("content-type") == "application/pdf":
                            pdf_url = response.url

                    # 监听新页面的网络响应
                    page.context.on("response", handle_response)

                    # 点击链接并等待新页面加载
                    with page.context.expect_page() as new_page_info:
                        project_three.click()
                    new_page = new_page_info.value
                
                    # 等待一段时间以确保响应被捕获
                    new_page.wait_for_timeout(5000)  # 等待 5 秒

                    # 检查是否捕获到 PDF URL
                    if pdf_url:
                        # 使用 requests 下载 PDF 文件
                        response = requests.get(pdf_url)

                        # 保存文件到指定目录
                        save_dir = f"./output/{project_name_one}/{project_name_two}"
                        if not os.path.exists(save_dir):
                            os.makedirs(save_dir)
                        with open(f"{save_dir}/{project_name_three}", "wb") as f:
                            f.write(response.content)
                        print(f"已下载: {project_name_three}")
                    else:
                        print("未捕获到 PDF 文件流")

                    # 移除监听器
                    page.context.remove_listener("response", handle_response)

                    # 关闭新页面
                    new_page.close()

                    # 跳转到原页面
                    page.bring_to_front()

                    # TODO: 等待页面加载完成
                    page.wait_for_timeout(1000)
                except Exception as e:
                    print(f"下载失败: {e}")
            # 返回项目清单页面
            page.locator("iframe[name=\"MainRight\"]").content_frame.get_by_text("返回列表").click()

            # TODO: 等待页面加载完成
            page.wait_for_timeout(2000)

        # 返回项目清单页面
        page.locator("iframe[name=\"MainRight\"]").content_frame.get_by_role("button", name="返回组列表").click()

        # TODO: 等待页面加载完成
        page.wait_for_timeout(2000)
    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)
